/* **********************************************************************************
*
* Copyright (c) Microsoft Corporation. All rights reserved.
*
* This source code is subject to terms and conditions of the Shared Source License
* for DSL Editor PowerToy. A copy of the license can be found in the License.htm file
* at the root of this distribution. If you can not locate the Shared Source License
* for DSL Editor PowerToy, please obtain a copy from: http://www.codeplex.com/dsltreegrideditor/Project/License.aspx.
* By using this source code in any fashion, you are agreeing to be bound by
* the terms of the Shared Source License for DSL Editor PowerToy.
*
* You must not remove this notice, or any other, from this software.
*
* **********************************************************************************/
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel.Design;
using System.Reflection;
using System.Text;
using System.Windows.Forms;

using Microsoft.VisualStudio;
using Microsoft.VisualStudio.Modeling.Shell;
using Microsoft.VisualStudio.Shell.Interop;

namespace DslEditorPowerToy.Controls.Languages.ToolWindows
{
    /// <summary>
    /// Toolwindow that acts as container for a editor host
    /// </summary>
    [CLSCompliant(false)]
    public abstract class EditorHostContainerBase : ControlHostBase, IEditorHostContainer
    {
        private EditorHostControl _control = null;

        #region Constructors
        public EditorHostContainerBase(IServiceProvider serviceProvider, Type dslLanguageDocViewType, Assembly editorDeclaringAssembly)
            : base(serviceProvider, dslLanguageDocViewType)
        {
            this._control = new EditorHostControl(editorDeclaringAssembly);
            this._control.EditorChanged += new EventHandler(_control_EditorChanged);
        }
        #endregion

        #region IEditorHostContainer Members

        /// <summary>
        /// Gets the current editor
        /// </summary>
        public IHostedEditorDefinition CurrentEditor
        {
            get
            {
                return this._control.CurrentEditor;
            }
        }
        /// <summary>
        /// Gets and sets the navigation style for the editors
        /// </summary>
        public NavigationOrientationStyle NavigationStyle
        {
            get
            {
                return this._control.NavigationStyle;
            }
            set
            {
                this._control.NavigationStyle = value;
            }
        }
        /// <summary>
        /// Activates specified editor
        /// </summary>
        public void ActivateEditor(Guid editorId)
        {
            this._control.ActivateEditor(editorId);
        }
        /// <summary>
        /// Gets list of editors
        /// </summary>
        public List<IHostedEditorDefinition> Editors
        {
            get
            {
                return this._control.GetEditors();
            }
        }        

        #endregion

        #region Protected Properties
        /// <summary>
        /// Gets the contained control
        /// </summary>
        protected override Control Control
        {
            get
            {
                return this._control;
            }
        }
        #endregion

        #region Protected Methods
        protected override void Dispose(bool disposing)
        {
            try
            {
                if (disposing)
                {
                    if (null != this._control)
                    {
                        this._control.EditorChanged -= new EventHandler(_control_EditorChanged);
                        this._control.Dispose();
                    }
                }
            }
            finally
            {
                base.Dispose(disposing);
            }
        }
        /// <summary>
        /// Handles change in editor
        /// </summary>
        protected virtual void OnEditorChanged()
        {
            ModifyWindowTitle();
        }
        protected override void OnDocumentWindowChanged(ModelingDocView oldView, ModelingDocView newView)
        {
            base.OnDocumentWindowChanged(oldView, newView);

            //Set the docView (first chance)
            if (null == this.DocView)
                this._control.CurrentDocData = null;
            else
                this._control.CurrentDocData = this.DocView.DocData;
        }
        #endregion

        #region Control Handlers
        /// <summary>
        /// Handles changes in editor
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void _control_EditorChanged(object sender, EventArgs e)
        {
            OnEditorChanged();
        }
        #endregion

        #region Private Methods
        /// <summary>
        /// Updates the window title to reflect current editor
        /// </summary>
        private void ModifyWindowTitle()
        {
            //Ensure there is an editor
            if ((null == this.CurrentEditor) 
                || (true == string.IsNullOrEmpty(this.CurrentEditor.Caption)))
                return;

            //Ensure we have more than one editor
            if (!(this.Editors.Count > 1))
                return;

            //Update window title
            string title = string.Format("{0} - [{1}]", this.WindowTitle, 
                this.CurrentEditor.Caption);
            SetWindowTitle(title);
        }
        /// <summary>
        /// Sets the title of the window
        /// </summary>
        /// <param name="title"></param>
        private void SetWindowTitle(string title)
        {
            IVsWindowFrame frame = base.Frame;
            if (null != frame)
                ErrorHandler.ThrowOnFailure(frame.SetProperty(-3004, title));
        }
        #endregion
    }
}
